iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0
自我挑戰組

asp.net可以變出那些功能系列 第 26

現在很流行的VUE

  • 分享至 

  • xImage
  •  

https://laihao2.com/Home/Contact20
https://ithelp.ithome.com.tw/upload/images/20241003/20119035UWvBJDzJ25.png

ASP.NET開發操作流程:資料表設定好>再寫程式:加入資料庫>串聯資料庫>產生Models裡面類別檔dao>按:建置>Controllers裡面的Entities>產生畫面View

這裡沒有用到資料表~

Controllers裡面的Entities>

public ActionResult Contact20()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

解釋程式碼
這段 C# 程式碼定義了一個名為 Contact20 的方法,該方法屬於一個控制器類別。這裡是逐行解釋:

  1. public ActionResult Contact20()
    這行宣告了一個名為 Contact20 的方法,該方法返回 ActionResult 類型。ActionResult 是 ASP.NET MVC 中的一個類型,用來表示控制器操作的結果。public 表示這個方法可以從類別外部訪問。

  2. ViewBag.Message = "Your contact page.";
    這行程式碼使用 ViewBag,這是一個動態物件,允許在控制器和視圖之間傳遞數據。這裡,Message 被設置為 "Your contact page.",這樣可以在與這個方法相關聯的視圖中顯示這個消息。

  3. return View();
    這行指示控制器返回一個視圖。ASP.NET MVC 的 View() 方法會渲染與此控制器方法同名的視圖(在這裡是 Contact20.cshtml),並將結果呈現給用戶。

總結:當請求到達 Contact20 方法時,控制器會設置一個名為 Message 的變數,然後返回一個與 Contact20 方法同名的視圖,該視圖將顯示 "Your contact page." 的信息。

產生畫面View程式碼

@{
    ViewBag.Title = "Contact20";
}
<h3></h3>
<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href='@Url.Content("~/Content/css/reset.css")'>
    <title>VUE前端技術</title>
    <style>
        img {
            border-radius: 50%;
        }

        body {
            background-color: lightskyblue;
            margin: 0;
            padding-top: 60px; /* 為導覽列騰出空間 */
        }

        .content-container {
            text-align: center;
            max-width: 600px;
            margin: 0 auto; /* 水平居中 */
            padding: 20px;
        }

        dl {
            margin-left: 20px;
        }

        dd {
            margin-left: 20px;
        }

        .button-container {
            display: flex;
            flex-direction: column;
            gap: 10px;
            align-items: center;
        }

        .pink-button {
            background-color: pink;
            color: black;
            padding: 10px 20px;
            text-decoration: none;
            border-radius: 5px;
            display: inline-block;
            text-align: center;
            transition: background-color 0.3s;
            width: 200px;
        }

            .pink-button:hover {
                background-color: #ff69b4;
            }
    </style>
</head>
<body>
    <!-- 增加 id="app" 以便 Vue 實例綁定 -->
    <div id="app" class="container">
        <div class="row">
            <div class="col-12">
                <div class="form-group">
                    <label>廠別</label>
                    <!-- 確保 change 正確綁定到 setSection 方法 -->
                    @*<select class="form-control" v-model="factory" @change="setSection">
                            <option v-for="item in factorys" :value="item.id">{{ item.name }}</option>
                        </select>*@

                    <select class="form-control" v-model="factory" @@change="setSection">
                        <option v-for="item in factorys" :value="item.id">{{ item.name }}</option>
                    </select>
                </div>
                <div class="form-group">
                    <label>課別</label>
                    <select class="form-control" v-model="section" :disabled="!filteredSections.length">
                        <option v-for="item in filteredSections" :value="item.id">{{ item.name }}</option>
                    </select>
                </div>

                <table class="table">
                    <thead>
                        <tr>
                            <th>工號</th>
                            <th>姓名</th>
                            <th>性別</th>
                        </tr>
                    </thead>
                    <tbody>
                        <!-- 根據條件過濾 section 和 factory -->
                        <tr v-for="item in employees" v-if="(section === null || item.section_id == section) && factory == sections.find(s => s.id == item.section_id).factory_id">
                            <td>{{ item.id }}</td>
                            <td>{{ item.name }}</td>
                            <td>{{ item.sex == 'M' ? '男' : '女' }}</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
    <script>
        var app = new Vue({
            el: '#app', // 綁定到帶有 id="app" 的元素
            data: {
                factory: 2, // 默認選中 factory 2
                section: null,
                factorys: [
                    { id: 1, name: '一廠' },
                    { id: 2, name: '二廠' }
                ],
                sections: [
                    { id: 1, name: '一廠辦公室', factory_id: 1 },
                    { id: 2, name: '管理部', factory_id: 1 },
                    { id: 3, name: '二廠辦公室', factory_id: 2 }
                ],
                employees: [
                    { id: 'A0001', name: '王小傑', sex: 'M', section_id: 1 },
                    { id: 'A0002', name: '陳小萱', sex: 'F', section_id: 1 },
                    { id: 'A0003', name: '吳小真', sex: 'F', section_id: 2 },
                    { id: 'A0004', name: '杜小憲', sex: 'M', section_id: 3 }
                ]
            },
            computed: {
                // 根據選中的 factory 過濾 sections
                filteredSections: function () {
                    return this.sections.filter(section => section.factory_id == this.factory);
                }
            },
            methods: {
                setSection: function () {
                    this.section = null;
                    const matchedSections = this.sections.filter(section => section.factory_id == this.factory);
                    if (matchedSections.length > 0) {
                        this.section = matchedSections[0].id; // 默認選擇第一個 section
                    }
                }
            },
            created: function () {
                this.setSection(); // 頁面加載時初始化 section
            }
        });
    </script>
</body>
</html>

解釋程式碼
這段程式碼是一個使用 Vue.js 的範例,通過雙向數據綁定來動態顯示廠別、課別和員工的列表。下面逐步解釋程式碼的結構和功能:

1. Razor 部分

@{
    ViewBag.Title = "Contact20";
}
<h3></h3>
  • ViewBag.Title = "Contact20";: 設置頁面標題為 "Contact20"。
  • 空的 <h3> 標籤目前沒有內容,可以用來顯示標題或其他信息。

2. HTML 結構部分

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href='@Url.Content("~/Content/css/reset.css")'>
    <title>VUE前端技術</title>
    <style>
        /* 內聯的 CSS 樣式 */
    </style>
</head>
  • 這是標準的 HTML 文件頭,指定了語言、編碼,並包含外部樣式表 reset.css,用來重置瀏覽器的默認樣式。
  • title 設定為 "VUE前端技術",這是顯示在瀏覽器標題欄中的文字。

3. Vue.js 應用結構

<body>
    <div id="app" class="container">
        <div class="row">
            <div class="col-12">
                <!-- 廠別選擇器 -->
                <div class="form-group">
                    <label>廠別</label>
                    <select class="form-control" v-model="factory" @@change="setSection">
                        <option v-for="item in factorys" :value="item.id">{{ item.name }}</option>
                    </select>
                </div>

                <!-- 課別選擇器 -->
                <div class="form-group">
                    <label>課別</label>
                    <select class="form-control" v-model="section" :disabled="!filteredSections.length">
                        <option v-for="item in filteredSections" :value="item.id">{{ item.name }}</option>
                    </select>
                </div>

                <!-- 員工列表 -->
                <table class="table">
                    <thead>
                        <tr>
                            <th>工號</th>
                            <th>姓名</th>
                            <th>性別</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="item in employees" v-if="(section === null || item.section_id == section) && factory == sections.find(s => s.id == item.section_id).factory_id">
                            <td>{{ item.id }}</td>
                            <td>{{ item.name }}</td>
                            <td>{{ item.sex == 'M' ? '男' : '女' }}</td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>

重要部分:

  1. 廠別選擇器

    • 使用 v-model 綁定 factory,通過 Vue 的雙向數據綁定來控制選中的廠別。
    • v-for 迴圈顯示所有可選的廠別,並綁定 item.id 作為選項值。
    • 當用戶改變選項時,@@change="setSection" 調用 setSection 方法更新相關的課別。
  2. 課別選擇器

    • 使用 v-model 綁定 section,當選中的 factory 改變時,課別列表將自動更新。
    • :disabled="!filteredSections.length" 控制如果沒有可選課別時,禁用選擇器。
    • 顯示對應 factory 的課別,通過 v-forfilteredSections 過濾。
  3. 員工列表

    • 使用 v-for 迴圈顯示符合條件的員工,條件為選中的 sectionfactory 匹配對應員工的 section_idfactory_id
    • 性別顯示使用三元運算符轉換 'M''F' 分別為 "男" 和 "女"。

4. Vue.js 程式碼

<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            factory: 2, // 默認選中 factory 2
            section: null,
            factorys: [
                { id: 1, name: '一廠' },
                { id: 2, name: '二廠' }
            ],
            sections: [
                { id: 1, name: '一廠辦公室', factory_id: 1 },
                { id: 2, name: '管理部', factory_id: 1 },
                { id: 3, name: '二廠辦公室', factory_id: 2 }
            ],
            employees: [
                { id: 'A0001', name: '王小傑', sex: 'M', section_id: 1 },
                { id: 'A0002', name: '陳小萱', sex: 'F', section_id: 1 },
                { id: 'A0003', name: '吳小真', sex: 'F', section_id: 2 },
                { id: 'A0004', name: '杜小憲', sex: 'M', section_id: 3 }
            ]
        },
        computed: {
            // 根據選中的 factory 過濾課別
            filteredSections: function () {
                return this.sections.filter(section => section.factory_id == this.factory);
            }
        },
        methods: {
            // 當廠別改變時,更新課別
            setSection: function () {
                this.section = null;
                const matchedSections = this.sections.filter(section => section.factory_id == this.factory);
                if (matchedSections.length > 0) {
                    this.section = matchedSections[0].id; // 默認選擇第一個課別
                }
            }
        },
        created: function () {
            this.setSection(); // 頁面加載時初始化 section
        }
    });
</script>

重要部分:

  1. data

    • 定義了 factory, sectionfactoryssections,以及 employees 這些數據,控制選擇的廠別和課別,並提供初始的廠別、課別和員工資料。
    • factory 默認選中 2廠,用來控制頁面的初始顯示狀態。
  2. computed

    • filteredSections: 根據當前選中的 factory 過濾課別,只顯示屬於該廠別的課別。
  3. methods

    • setSection: 當用戶改變廠別時,重置課別,並默認選擇第一個匹配的課別。
  4. created

    • Vue 的 created 生命週期鉤子,頁面加載時會自動初始化課別。

總結

這段程式碼實現了一個簡單的前端介面,通過 Vue.js 動態顯示不同廠別的課別和員工列表。當用戶選擇不同的廠別時,課別和員工會根據選擇自動過濾顯示。

要特別注意的地方:
報錯訊息「The name 'change' does not exist in the current context」是因為在你的 ASP.NET MVC 視圖中,使用了 @change 時,Razor 語法引擎誤以為這是一個 C# 表達式,而不是 Vue.js 的指令。

解決方法

Razor 視圖引擎使用 @ 開頭來處理 C# 語法,而 Vue.js 也使用 @ 來表示事件綁定(如 @click@change)。當 Razor 引擎遇到 @change 時,它會誤解為 C# 語法,導致找不到該名稱。

解決方案:將 @ 字元轉義

你可以使用 @change@ 字元轉義方式來告訴 Razor 這是一個字面量,不是 C# 語法。可以使用 @ 前加上一個 @ 字元來告訴 Razor 忽略該部分:

<select class="form-control" v-model="factory" @@change="setSection">
    <option v-for="item in factorys" :value="item.id">{{ item.name }}</option>
</select>

這樣的寫法告訴 Razor,這是 Vue.js 的 @change 事件處理,而不是 Razor 的 C# 語法。這樣就不會再出現「The name 'change' does not exist in the current context」的錯誤。

完整修改範例

<select class="form-control" v-model="factory" @@change="setSection">
    <option v-for="item in factorys" :value="item.id">{{ item.name }}</option>
</select>

記得:Vue.js 的 @change 或其他事件指令,當你在 ASP.NET MVC 中使用 Razor 視圖時,記得加上一個額外的 @ 來轉義這些 Vue.js 的指令。

大家明天見~/images/emoticon/emoticon01.gif


上一篇
圖片輪播:極簡風/跳出視窗提示:現代風
下一篇
簡約風
系列文
asp.net可以變出那些功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言